home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / asm / desc.h < prev    next >
C/C++ Source or Header  |  2005-10-13  |  3KB  |  141 lines

  1. #ifndef __ARCH_DESC_H
  2. #define __ARCH_DESC_H
  3.  
  4. #include <asm/ldt.h>
  5. #include <asm/segment.h>
  6.  
  7. #ifndef __ASSEMBLY__
  8.  
  9. #include <linux/preempt.h>
  10. #include <linux/smp.h>
  11. #include <linux/percpu.h>
  12.  
  13. #include <asm/mmu.h>
  14.  
  15. extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
  16. DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
  17.  
  18. struct Xgt_desc_struct {
  19.     unsigned short size;
  20.     unsigned long address __attribute__((packed));
  21.     unsigned short pad;
  22. } __attribute__ ((packed));
  23.  
  24. extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
  25.  
  26. #define load_TR_desc() __asm__ __volatile__("ltr %%ax"::"a" (GDT_ENTRY_TSS*8))
  27. #define load_LDT_desc() __asm__ __volatile__("lldt %%ax"::"a" (GDT_ENTRY_LDT*8))
  28.  
  29. /*
  30.  * This is the ldt that every process will get unless we need
  31.  * something other than this.
  32.  */
  33. extern struct desc_struct default_ldt[];
  34. extern void set_intr_gate(unsigned int irq, void * addr);
  35.  
  36. #define _set_tssldt_desc(n,addr,limit,type) \
  37. __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
  38.     "movw %%ax,2(%2)\n\t" \
  39.     "rorl $16,%%eax\n\t" \
  40.     "movb %%al,4(%2)\n\t" \
  41.     "movb %4,5(%2)\n\t" \
  42.     "movb $0,6(%2)\n\t" \
  43.     "movb %%ah,7(%2)\n\t" \
  44.     "rorl $16,%%eax" \
  45.     : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
  46.  
  47. static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
  48. {
  49.     _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[entry], (int)addr,
  50.         offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
  51. }
  52.  
  53. #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
  54.  
  55. static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
  56. {
  57.     _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
  58. }
  59.  
  60. #define LDT_entry_a(info) \
  61.     ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
  62.  
  63. #define LDT_entry_b(info) \
  64.     (((info)->base_addr & 0xff000000) | \
  65.     (((info)->base_addr & 0x00ff0000) >> 16) | \
  66.     ((info)->limit & 0xf0000) | \
  67.     (((info)->read_exec_only ^ 1) << 9) | \
  68.     ((info)->contents << 10) | \
  69.     (((info)->seg_not_present ^ 1) << 15) | \
  70.     ((info)->seg_32bit << 22) | \
  71.     ((info)->limit_in_pages << 23) | \
  72.     ((info)->useable << 20) | \
  73.     0x7000)
  74.  
  75. #define LDT_empty(info) (\
  76.     (info)->base_addr    == 0    && \
  77.     (info)->limit        == 0    && \
  78.     (info)->contents    == 0    && \
  79.     (info)->read_exec_only    == 1    && \
  80.     (info)->seg_32bit    == 0    && \
  81.     (info)->limit_in_pages    == 0    && \
  82.     (info)->seg_not_present    == 1    && \
  83.     (info)->useable        == 0    )
  84.  
  85. #if TLS_SIZE != 24
  86. # error update this code.
  87. #endif
  88.  
  89. static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
  90. {
  91. #define C(i) per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
  92.     C(0); C(1); C(2);
  93. #undef C
  94. }
  95.  
  96. static inline void clear_LDT(void)
  97. {
  98.     int cpu = get_cpu();
  99.  
  100.     set_ldt_desc(cpu, &default_ldt[0], 5);
  101.     load_LDT_desc();
  102.     put_cpu();
  103. }
  104.  
  105. /*
  106.  * load one particular LDT into the current CPU
  107.  */
  108. static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
  109. {
  110.     void *segments = pc->ldt;
  111.     int count = pc->size;
  112.  
  113.     if (likely(!count)) {
  114.         segments = &default_ldt[0];
  115.         count = 5;
  116.     }
  117.         
  118.     set_ldt_desc(cpu, segments, count);
  119.     load_LDT_desc();
  120. }
  121.  
  122. static inline void load_LDT(mm_context_t *pc)
  123. {
  124.     int cpu = get_cpu();
  125.     load_LDT_nolock(pc, cpu);
  126.     put_cpu();
  127. }
  128.  
  129. static inline unsigned long get_desc_base(unsigned long *desc)
  130. {
  131.     unsigned long base;
  132.     base = ((desc[0] >> 16)  & 0x0000ffff) |
  133.         ((desc[1] << 16) & 0x00ff0000) |
  134.         (desc[1] & 0xff000000);
  135.     return base;
  136. }
  137.  
  138. #endif /* !__ASSEMBLY__ */
  139.  
  140. #endif
  141.